#!/usr/bin/ruby
#-*- coding: UTF-8 -*-
require 'xcodeproj'
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

#直接修改使用
_xcodeProjPath = "/Volumes/trunkDisk/b3/0.0.4/frameworks/runtime-src/proj.ios_appstore_zhongshouyou_iosappstore_mlzs/arpg.xcodeproj"   #工程路径
_prefix = "WC"   #文件名和文件夹名前缀
#传参的方式使用
# _xcodeProjPath = ARGV[0]
# _prefix = ARGV[1]

sdkEntranceFilePath = File::dirname(_xcodeProjPath) + "/ios/jooyuusdk/SDKEntrance.mm"
$platform_project = Xcodeproj::Project.open(_xcodeProjPath)
$platform_target = $platform_project.targets[0]
$lastFileName = ""

def get_rand_str (str_len)
	azAZ = ("a".."z").to_a + ("A".."Z").to_a
	rand_str = ""
	str_len.times do
		rand_str << azAZ.sample
	end
	rand_str
end

def createGroup (groupName)
	group = $platform_project.new_group(groupName,groupName)
	Dir::mkdir(group.real_path)
	return group
end

def getParameterType
	index = rand(0..2)
	if index == 0
		return "(NSString *)"
	elsif index == 1
		return "(NSInteger)"
	elsif index == 2
		return "(NSArray *)"
	end
end

def getHeaderRandMethodName
	parametersCount = rand(0..4)
	methodBase = get_rand_str rand(5..8)
	methodStr = "- (void)#{methodBase}"
	parametersCount.times do
		tip = get_rand_str rand(3..8)
		name = get_rand_str rand(3..8)
		methodStr = methodStr + tip + ":" + getParameterType + name + " "
	end
	methodStr = methodStr + ";"
	return methodStr
end

def getAllMethodOfHeaderFile (headerFilePath)
	file_object = File.open(headerFilePath,"r")
	methodsArray = Array.new(0)
	while line = file_object.gets 
		if line.include? "-"
			methodsArray = methodsArray << line
		end
	end
	return methodsArray
end

def getUsageOfMethod(originMethodStr,object,integerArray,stringArray,arrayArray)
	originMethod = originMethodStr.sub(";","")
	originMethod = originMethod.sub("- (void)","")
	originMethod = originMethod.strip
	lastMethod = originMethod.gsub(/(\(.*?\)\w*\b)/) { |matchStr| 
			if matchStr.match(/(\(.*NSInteger.*\))/)
				if integerArray.empty?
					rand(10..200)
				else
					index = rand(0..(integerArray.length - 1))
					integerArray[index].last
				end
			elsif matchStr.match(/(\(.*NSString.*\*.*\))/)
				if stringArray.empty?
					tmpStr = get_rand_str rand(2.. 10)
					"@\"#{tmpStr}\""
				else
					index = rand(0..(stringArray.length - 1))
					stringArray[index].last
				end
			elsif matchStr.match(/(\(.*NSArray.*\*.*\))/)
				if arrayArray.empty?
					"[NSArray new]"
				else
					index = rand(0..(arrayArray.length - 1))
					arrayArray[index].last
				end
			end
	}

	return "[[#{object} new] " + lastMethod + "];"
end

def getArchieveAndUsageOfMethod (currentLine,lastLine,object)
	integerArray = currentLine.scan(/\(.?NSInteger.?\)(\w*)\b/)
	stringArray = currentLine.scan(/\(.?NSString.?\*.?\)(\w*)\b/)
	arrayArray = currentLine.scan(/\(.?NSArray.?\*.?\)(\w*)\b/)
	method = ""
	if !lastLine.empty? and !object.empty?
		achieveStr = getUsageOfMethod lastLine,object,integerArray,stringArray,arrayArray
		method = method + "\t" + achieveStr + "\n"
	else
		randStr = get_rand_str rand(2..5)
		method = method + "\t" + "NSInteger #{randStr} = #{rand(2..200)};\n"
		integerArray.each { |number|
			randStr = get_rand_str rand(2..5)
			method = method + "\t" + "NSInteger #{randStr} = #{number.last};\n"
		}
		stringArray.each { |string|
			randStr = get_rand_str rand(2..5)
			method = method + "\t" + "NSString *#{randStr} = #{string.last};\n"
		}
		arrayArray.each { |array|
			randStr = get_rand_str rand(2..5)
			method = method + "\t" + "NSArray *#{randStr} = [NSArray arrayWithArray:#{array.last}];\n"
		}
	end
	return method
end

def getAchieveMethodInHeaderFile (headerFilePath,groupPath,lastHeaderFileName) 
	lastFileMethodArray = Array.new(0)
	if !lastHeaderFileName.empty?
		lastFileMethodArray = getAllMethodOfHeaderFile "#{groupPath}/#{lastHeaderFileName}.h"
	end
	currentFileMethodArray = getAllMethodOfHeaderFile headerFilePath
	lastMethodsCount = lastFileMethodArray.length
	currentMethodsCount = currentFileMethodArray.length
	content = "\n"
	for i in 0..(currentMethodsCount - 1)
		currentLine = currentFileMethodArray[i]
		method = currentLine.sub(";","{\n")
		achieve = ""

		if i == (currentMethodsCount - 1) and i < (lastMethodsCount - 1)
			for j in i..(lastMethodsCount - 1)
				lastLine = ""
				lastLine = lastFileMethodArray[j]
				tmpAchieve = getArchieveAndUsageOfMethod currentLine,lastLine,lastHeaderFileName
				achieve = achieve + tmpAchieve + "\n"
			end
		else
			lastLine = ""
			if i < lastMethodsCount
				lastLine = lastFileMethodArray[i]
			elsif lastMethodsCount != 0
				lastLine = lastFileMethodArray[rand(0..(lastMethodsCount - 1))]
			end
			achieve = getArchieveAndUsageOfMethod currentLine,lastLine,lastHeaderFileName
		end
		
		method = method + achieve

		method = method + "\n}\n"
		content = content + method + "\n"
	end
	return content
end

def writeContentToFile (groupPath,fileName)
	headerPath = "#{groupPath}/#{fileName}.h"
	compilePath = "#{groupPath}/#{fileName}.m"

	headerFile = File.open(headerPath,"w")
	compileFile = File.open(compilePath,"w")

	headerFile.puts("#import <Foundation/Foundation.h>\n\n")
	headerFile.puts("@interface #{fileName} : NSObject\n\n")
	headerFileMethodCount = rand(5..10)
	headerFileMethodCount.times do
		method_name = getHeaderRandMethodName
		headerFile.puts(method_name)
	end
	headerFile.puts("\n")
	headerFile.puts("@end")
	headerFile.close

	compileFile.puts("#import \"#{fileName}.h\"\n")
	if $lastFileName.empty?
		compileFile.puts("\n")
	else
		compileFile.puts("#import \"#{$lastFileName}.h\"\n\n")
	end
	compileFile.puts("@implementation #{fileName}\n\n")
	achieveMethodContent = getAchieveMethodInHeaderFile headerPath,groupPath,$lastFileName
	compileFile.puts(achieveMethodContent)
	compileFile.puts("@end")
	compileFile.close
	$lastFileName = fileName
end

def createOCFile (fileName,group)
	headerPath = "#{group.real_path}/#{fileName}.h"
	compilePath = "#{group.real_path}/#{fileName}.m"

	File.new(headerPath,'wb+')
	File.new(compilePath,'wb+')

	header_reference = group.new_reference(headerPath)
	compile_reference = group.new_reference(compilePath)

	$platform_target.add_file_references(Array.new(1) { compile_reference })

	writeContentToFile group.real_path,fileName
end

confusion_group = createGroup "#{_prefix}Group"
fileCount = rand(10..15)
fileCount.times do
	str_len = rand(10..15)
	rand_str = get_rand_str str_len
	fileName = "#{_prefix}#{rand_str}"
	createOCFile fileName,confusion_group
end
sdkEntranceFile = File.open(sdkEntranceFilePath, "r")
sdkEntranceContent = sdkEntranceFile.read
sdkEntranceContent = sdkEntranceContent.sub(/#import/,"#import \"#{$lastFileName}.h\"\n#import")
sdkEntranceContent = sdkEntranceContent.sub(/(-.*\(.*void.*\).*doLoginout(.*|.*\n).*\{)/) { |match| 
	methosToAddArray = getAllMethodOfHeaderFile "#{confusion_group.real_path}/#{$lastFileName}.h"
	usageOfMethod = ""
	for i in 0..(methosToAddArray.length - 1)
		lastLine = methosToAddArray[i]
		currentLine = ""
		tmpAchieve = getArchieveAndUsageOfMethod currentLine,lastLine,$lastFileName
		usageOfMethod = usageOfMethod + tmpAchieve + "\n"
	end
	back_str = match + "\n" + usageOfMethod + "\n"
	back_str
}
sdkEntranceFile.reopen(sdkEntranceFilePath,"w")
sdkEntranceFile.syswrite(sdkEntranceContent)
sdkEntranceFile.close

puts "**************************引头文件名***************"
puts $lastFileName
puts "*************************************************"
$platform_project.save